'use strict';
const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');
const fs = require('fs');
const path = require('path');

module.exports = class extends Generator {
  constructor(args, opts) {
    super(args, opts);
    
    // 检测项目根目录
    this.projectRoot = this._findProjectRoot();
    this.log(`检测到项目根目录: ${this.projectRoot}`);
  }
  
  // 查找项目根目录的方法
  _findProjectRoot() {
    let currentDir = process.cwd();
    let rootDir = currentDir;
    
    // 向上查找，直到找到包含pom.xml和hello-modules目录的目录
    while (currentDir) {
      // 检查当前目录是否包含pom.xml和hello-modules目录
      if (
        fs.existsSync(path.join(currentDir, 'pom.xml')) && 
        fs.existsSync(path.join(currentDir, 'hello-modules')) &&
        fs.existsSync(path.join(currentDir, 'hello-common'))
      ) {
        return currentDir;
      }
      
      // 向上一级目录
      const parentDir = path.dirname(currentDir);
      if (parentDir === currentDir) {
        // 已经到达根目录，无法再向上
        break;
      }
      currentDir = parentDir;
    }
    
    // 如果找不到，则返回当前目录
    return rootDir;
  }

  prompting() {
    // 欢迎信息
    this.log(
      yosay(`欢迎使用 ${chalk.red('Hello微服务')} 模块生成器!`)
    );

    const prompts = [
      {
        type: 'input',
        name: 'moduleName',
        message: '请输入模块名称 (例如: hello-demo):',
        default: 'hello-demo'
      },
      {
        type: 'input',
        name: 'moduleDescription',
        message: '请输入模块描述:',
        default: '新的Hello微服务模块'
      },
      {
        type: 'input',
        name: 'serverPort',
        message: '请输入服务端口号:',
        default: '8080'
      },
      {
        type: 'input',
        name: 'basePackage',
        message: '请输入基础包名:',
        default: 'com.hello'
      },
      {
        type: 'list',
        name: 'moduleType',
        message: '请选择模块类型:',
        choices: [
          {
            name: '业务模块 (包含Controller/Service/Mapper)',
            value: 'business'
          },
          {
            name: '通用模块 (仅基础结构)',
            value: 'common'
          }
        ],
        default: 'business'
      },
      {
        type: 'confirm',
        name: 'includeRedis',
        message: '是否需要Redis支持?',
        default: false
      },
      {
        type: 'confirm',
        name: 'includeSecurity',
        message: '是否需要Security安全支持?',
        default: true
      }
    ];

    return this.prompt(prompts).then(props => {
      // 保存用户输入的配置
      this.props = props;
    });
  }

  writing() {
    // 生成项目目录结构
    this._createProjectStructure();
    
    // 生成Maven配置文件
    this._createMavenConfig();
    
    // 生成Java源码文件
    this._createJavaFiles();
    
    // 生成配置文件
    this._createConfigFiles();
  }

  _createProjectStructure() {
    const moduleName = this.props.moduleName;
    const modulesDir = path.join(this.projectRoot, 'hello-modules');
    
    // 创建目录结构
    this.fs.copy(
      this.templatePath('gitignore'),
      this.destinationPath(path.join(modulesDir, moduleName, '.gitignore'))
    );
    
    // 创建src目录结构
    this.fs.copy(
      this.templatePath('src/main/resources/banner.txt'),
      this.destinationPath(path.join(modulesDir, moduleName, 'src/main/resources/banner.txt'))
    );
    
    // 创建部署目录
    this.fs.copyTpl(
      this.templatePath('deploy/Dockerfile'),
      this.destinationPath(path.join(modulesDir, moduleName, 'deploy/Dockerfile')),
      {
        moduleName: moduleName
      }
    );
  }

  _createMavenConfig() {
    const moduleName = this.props.moduleName;
    const basePackage = this.props.basePackage;
    const moduleNameWithoutPrefix = moduleName.replace(/^hello-/, '');
    const modulesDir = path.join(this.projectRoot, 'hello-modules');
    
    // 生成pom.xml
    this.fs.copyTpl(
      this.templatePath('pom.xml'),
      this.destinationPath(path.join(modulesDir, moduleName, 'pom.xml')),
      {
        moduleName: moduleName,
        moduleNameWithoutPrefix: moduleNameWithoutPrefix,
        moduleDescription: this.props.moduleDescription,
        basePackage: basePackage,
        includeRedis: this.props.includeRedis,
        includeSecurity: this.props.includeSecurity
      }
    );
  }

  _createJavaFiles() {
    const moduleName = this.props.moduleName;
    const basePackage = this.props.basePackage;
    const pkgPath = basePackage.replace(/\./g, '/');
    const moduleNameWithoutPrefix = moduleName.replace(/^hello-/, '');
    const modulesDir = path.join(this.projectRoot, 'hello-modules');
    
    // 生成类名 - 将模块名转换为驼峰格式并添加Application后缀
    const className = this._generateClassName(moduleNameWithoutPrefix);
    
    // 创建主应用类
    this.fs.copyTpl(
      this.templatePath('src/main/java/Application.java'),
      this.destinationPath(path.join(modulesDir, moduleName, 'src/main/java', pkgPath, moduleNameWithoutPrefix, `${className}.java`)),
      {
        basePackage: basePackage,
        moduleNameWithoutPrefix: moduleNameWithoutPrefix,
        className: className
      }
    );
    
    // 如果是业务模块，则只创建Controller/Service/Mapper目录结构，不生成示例文件
    if (this.props.moduleType === 'business') {
      // 创建控制器目录
      this.fs.write(
        this.destinationPath(path.join(modulesDir, moduleName, 'src/main/java', pkgPath, moduleNameWithoutPrefix, 'controller/.gitkeep')),
        ''
      );
      
      // 创建服务目录
      this.fs.write(
        this.destinationPath(path.join(modulesDir, moduleName, 'src/main/java', pkgPath, moduleNameWithoutPrefix, 'service/.gitkeep')),
        ''
      );
      
      // 创建映射器目录
      this.fs.write(
        this.destinationPath(path.join(modulesDir, moduleName, 'src/main/java', pkgPath, moduleNameWithoutPrefix, 'mapper/.gitkeep')),
        ''
      );
    }
  }

  // 生成类名的方法 - 将模块名转换为驼峰式并添加Application后缀
  _generateClassName(moduleNameWithoutPrefix) {
    // 将模块名按连字符或下划线分割
    const parts = moduleNameWithoutPrefix.split(/[-_]/);
    
    // 将每部分首字母大写
    const camelCaseName = parts.map(part => 
      part.charAt(0).toUpperCase() + part.slice(1)
    ).join('');
    
    // 返回类名
    return `Hello${camelCaseName}Application`;
  }

  _createConfigFiles() {
    const moduleName = this.props.moduleName;
    const basePackage = this.props.basePackage;
    const moduleNameWithoutPrefix = moduleName.replace(/^hello-/, '');
    const modulesDir = path.join(this.projectRoot, 'hello-modules');
    
    // 创建application.yml
    this.fs.copyTpl(
      this.templatePath('src/main/resources/application.yml'),
      this.destinationPath(path.join(modulesDir, moduleName, 'src/main/resources/application.yml')),
      {
        moduleName: moduleName,
        basePackage: basePackage,
        moduleNameWithoutPrefix: moduleNameWithoutPrefix
      }
    );
    
    // 创建bootstrap.yml
    this.fs.copyTpl(
      this.templatePath('src/main/resources/bootstrap.yml'),
      this.destinationPath(path.join(modulesDir, moduleName, 'src/main/resources/bootstrap.yml')),
      {
        moduleName: moduleName,
        serverPort: this.props.serverPort
      }
    );
  }

  install() {
    this.log(chalk.green('项目结构已生成完成!'));
  }

  end() {
    this.log('');
    this.log(chalk.green('Hello微服务模块已创建成功!'));
    this.log('');
    this.log(`可以通过以下步骤添加到项目：`);
    this.log(chalk.yellow(`1. 模块已经在 ${path.join(this.projectRoot, 'hello-modules', this.props.moduleName)} 目录下生成`));
    this.log(chalk.yellow(`2. 请编辑 ${path.join(this.projectRoot, 'hello-modules', 'pom.xml')} 文件`));
    this.log(chalk.yellow(`3. 在 <modules> 标签内添加: <module>${this.props.moduleName}</module>`));
    this.log(chalk.yellow(`4. 执行 mvn clean install -DskipTests 重新构建项目`));
    this.log('');
  }
};